package com.huan.pdf.utils;

import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;

/**
 * pdf工具类
 *
 * @author admin
 */
@Slf4j
public class PdfUtils {

    /**
     * 转换成pdf字节流
     *
     * @param pdfTemplate HTML 模板字符串
     */
    public static byte[] toPdfBytes(String pdfTemplate) {
        // 1. 先用 openhtmltopdf 生成未加密 PDF（内存）
        ByteArrayOutputStream temp = new ByteArrayOutputStream();
        try {
            PdfRendererBuilder builder = new PdfRendererBuilder();
            builder.useFont(() -> PdfUtils.class.getClassLoader().getResourceAsStream("fonts/simsun.ttf"), "SimSun");

            // 系统中静态资源的目录位置，可选
            Path path = Paths.get("D:\\code_p3c\\gitee\\spring-cloud-parent\\pdf\\openhtmltopdf\\src\\main\\resources");
            String staticFilePath = path.toUri().toString();

            builder.withHtmlContent(pdfTemplate, staticFilePath);
            builder.toStream(temp);
            // 完成渲染
            builder.run();
        } catch (IOException e) {
            log.error("生成PDF失败", e);
            throw new RuntimeException("生成PDF失败");
        }
        return temp.toByteArray();
    }

    /**
     * 生成带密码的 PDF 文件（用户密码 a0min13s）
     *
     * @param pdfTemplate HTML 模板字符串
     * @param response    HTTP 响应
     */
    public static void generatePdf(String pdfTemplate, HttpServletResponse response) {
        String fileName = UUID.randomUUID() + ".pdf";
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);

        // 1. 先用 openhtmltopdf 生成未加密 PDF（内存）
        ByteArrayOutputStream temp = new ByteArrayOutputStream();
        try {
            PdfRendererBuilder builder = new PdfRendererBuilder();
            builder.useFont(() -> PdfUtils.class.getClassLoader().getResourceAsStream("fonts/simsun.ttf"), "SimSun");

            // 系统中静态资源的目录位置，可选
            Path path = Paths.get("D:\\code_p3c\\gitee\\spring-cloud-parent\\pdf\\openhtmltopdf\\src\\main\\resources");
            String staticFilePath = path.toUri().toString();

            builder.withHtmlContent(pdfTemplate, staticFilePath);
            builder.toStream(temp);
            // 完成渲染
            builder.run();
        } catch (IOException e) {
            log.error("生成PDF失败", e);
            throw new RuntimeException("生成PDF失败");
        }

        // 用 PDFBox 加载并加密
        try (PDDocument doc = PDDocument.load(temp.toByteArray());
             OutputStream os = response.getOutputStream()) {

            AccessPermission ap = new AccessPermission();
            // 可选：禁止打印、复制等
            ap.setCanPrint(false);
            ap.setCanExtractContent(false);

            // 用户密码，所有者密码一样即可（也可设不同）
            StandardProtectionPolicy policy =
                    // ownerPwd  userPwd
                    new StandardProtectionPolicy("a0min13s", "a0min13s", ap);
            // 128 位 AES
            policy.setEncryptionKeyLength(128);
            policy.setPermissions(ap);
            // 执行加密
            doc.protect(policy);
            // 写给浏览器
            doc.save(os);
            // 确保全部送出
            os.flush();
        } catch (IOException e) {
            log.error("PDF加密输出失败", e);
            throw new RuntimeException("PDF加密输出失败");
        }
    }
}
